package com.mashibing.remote;

import com.mashibing.internalcommon.constant.AmapConfigConstants;
import com.mashibing.internalcommon.dto.ResponseResult;
import com.mashibing.internalcommon.request.PointDTO;
import com.mashibing.internalcommon.request.PointRequest;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class uploadTrackClient {

    @Value("${amap.key}")
    private String amapKey;

    @Value("${amap.sid}")
    private String sid;


    @Autowired
    private RestTemplate restTemplate;

    public ResponseResult uploadTrack(PointRequest pointRequest) {

        // 组装url
        String url = urlBuild(pointRequest);
        log.info("高德地图：上传轨迹url：" + url);

        // 请求远程地址
        ResponseEntity<String> directionEntity = restTemplate.postForEntity(URI.create(url), null, String.class);
        log.info("高德地图：返回结果：" + directionEntity.getBody());

        JSONObject result = JSONObject.fromObject(directionEntity.getBody());
        String errmsg = result.getString("errmsg");

        return ResponseResult.success(errmsg);
    }

    public String urlBuild(PointRequest pointRequest) {

        StringBuilder urlBuild = new StringBuilder();
        urlBuild.append(AmapConfigConstants.POINT_UPLOAD);
        urlBuild.append("?");
        urlBuild.append("key=").append(amapKey);
        urlBuild.append("&");
        urlBuild.append("tid=").append(pointRequest.getTid());
        urlBuild.append("&");
        urlBuild.append("sid=").append(sid);
        urlBuild.append("&");
        urlBuild.append("trid=").append(pointRequest.getTrid());
        urlBuild.append("&");
        urlBuild.append("points=");

        // 拼接对应参数
        PointDTO[] points = pointRequest.getPoints();
        StringBuilder pointsBuilder = new StringBuilder();
        pointsBuilder.append("[");

        for (PointDTO pointDTO : points) {
            pointsBuilder.append("{");
            pointsBuilder.append("\"location\":" + "\"").append(pointDTO.getLocation()).append("\"").append(",");
            pointsBuilder.append("\"locatetime\":" + "\"").append(pointDTO.getLocatetime()).append("\"");
            pointsBuilder.append("}");
        }
        pointsBuilder.append("]");
        String encode = encode(pointsBuilder.toString());

        urlBuild.append(encode);
        return urlBuild.toString();
    }


    /**
     * 对输入字符串进行URL编码，遵循RFC 3986标准。
     *
     * @param input 待编码的字符串
     * @return 编码后的字符串，保留字母、数字及-_.~等安全字符
     */
    public String encode(String input) {
        if (input == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (isUnreserved(c)) {
                sb.append(c);
            } else {
                // 将字符转换为UTF-8字节数组并进行百分号编码
                byte[] bytes = String.valueOf(c).getBytes(StandardCharsets.UTF_8);
                for (byte b : bytes) {
                    sb.append('%');
                    sb.append(String.format("%02X", b)); // 转换为大写十六进制
                }
            }
        }
        return sb.toString();
    }

    /**
     * 判断字符是否为无需编码的安全字符（字母、数字、-_.~）
     *
     * @param c 待检查的字符
     * @return 如果是安全字符返回true，否则返回false
     */
    private boolean isUnreserved(char c) {
        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
                (c >= '0' && c <= '9') || c == '-' || c == '_' ||
                c == '.' || c == '~';
    }
}
